package com.atguigu.gmall.payment.controller;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.atguigu.gmall.common.bean.UserInfo;
import com.atguigu.gmall.common.exception.OrderException;
import com.atguigu.gmall.oms.entity.OrderEntity;
import com.atguigu.gmall.payment.config.AlipayTemplate;
import com.atguigu.gmall.payment.entity.PaymentInfoEntity;
import com.atguigu.gmall.payment.interceptor.LoginInterceptor;
import com.atguigu.gmall.payment.service.PayService;
import com.atguigu.gmall.payment.vo.PayAsyncVo;
import com.atguigu.gmall.payment.vo.PayVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.math.BigDecimal;
import java.util.Date;

@Controller
public class PayController {
    @Autowired
    private PayService payService;

    @Autowired
    private AlipayTemplate alipayTemplate;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @GetMapping("pay.html")
    public String pay(@RequestParam("orderToken")String orderToken, Model model){

        //判断订单是否存在
        OrderEntity orderEntity = this.payService.queryOrderByToken(orderToken);
        if (orderEntity == null){
            throw new OrderException("您支付的订单不存在！");
        }

        //判断当前订单是否属于登陆用户
        UserInfo userInfo = LoginInterceptor.getUserInfo();
        Long userId = userInfo.getUserId();
        if (orderEntity.getUserId() != userId){
            throw new OrderException("这个订单不属于您！");
        }

        //判断订单状态，待付款
        if (orderEntity.getStatus() != 0){
            throw new OrderException("这个订单不能支付！");
        }
        model.addAttribute("orderEntity",orderEntity);
        return "pay";
    }


    @GetMapping("alipay.html")
    @ResponseBody //以其他视图展示
    public String alipay(@RequestParam("orderToken")String orderToken){


        //判断订单是否存在
        OrderEntity orderEntity = this.payService.queryOrderByToken(orderToken);
        if (orderEntity == null){
            throw new OrderException("您支付的订单不存在！");
        }

        //判断当前订单是否属于登陆用户
        UserInfo userInfo = LoginInterceptor.getUserInfo();
        Long userId = userInfo.getUserId();
        if (orderEntity.getUserId() != userId){
            throw new OrderException("这个订单不属于您！");
        }

        //判断订单状态，待付款
        if (orderEntity.getStatus() != 0){
            throw new OrderException("这个订单不能支付！");
        }


        //调用接口，打开一个支付页面
        try {
            PayVo payVo = new PayVo();
            payVo.setOut_trade_no(orderEntity.getOrderSn());
            //支付金额 orderEntity.getPayAmount().toString()  建议写0.01
            payVo.setTotal_amount("0.01");
            payVo.setSubject("谷粒商城支付平台");

            //记录对账信息
            Long payId = this.payService.savePaymentInfo(payVo);

            payVo.setPassback_params(payId.toString());

            String form = this.alipayTemplate.pay(payVo);

            return form;
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        throw new OrderException("支付失败！");
    }

    /**
     * 支付宝同步回调路径
     * @return
     */
    @GetMapping("pay/success")
    public String paySuccess(){

        return "paysuccess";
    }

    /**
     * 支付宝异步回调路径
     * @return
     */
    @PostMapping("pay/ok")
    @ResponseBody
    public Object payOk(PayAsyncVo payAsyncVo){

        //1.验签
        Boolean flag = this.alipayTemplate.checkSignature(payAsyncVo);
        if (!flag){
            return "failure";
        }

        //2.校验订单的业务参数：app_id、out_trade_no、total_amount
        String appId = payAsyncVo.getApp_id();
        String outTradeNo = payAsyncVo.getOut_trade_no();
        String totalAmount = payAsyncVo.getTotal_amount();
        String payId = payAsyncVo.getPassback_params();
        PaymentInfoEntity paymentInfoEntity = this.payService.queryPaymentById(payId);
        //比较支付金额new一个BigDecimal比较，不用Stringutils。因为我们小数点后保留了4个0，支付宝保留了两个0
        if (!StringUtils.equals(appId,alipayTemplate.getApp_id())
                || !StringUtils.equals(outTradeNo,paymentInfoEntity.getOutTradeNo())
                || new BigDecimal(totalAmount).compareTo(paymentInfoEntity.getTotalAmount()) != 0
        ){
            return "failure";
        }

        //3.校验支付状态码： trade_status  TRADE_SUCCESS
        if (!StringUtils.equals("TRADE_SUCCESS",payAsyncVo.getTrade_status())){
            return "failure";
        }

        //4.更新对账表  已支付
        paymentInfoEntity.setPaymentStatus(1);
        paymentInfoEntity.setCallbackTime(new Date());
        paymentInfoEntity.setCallbackContent(JSON.toJSONString(payAsyncVo));
        if (this.payService.updatePayment(paymentInfoEntity) == 0) {
            return "failure";
        }

        //5.发送消息给oms修改订单状态，oms发送消息给wms减库存
        this.rabbitTemplate.convertAndSend("ORDER_EXCHANGE","order.pay",outTradeNo);

        return "success";
    }
}
